﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.Rendering;
using System;


namespace YYPostProcessing
{

    public class YYPostProcessLayer : MonoBehaviour
    {
        CommandBuffer m_LegacyCmdBuffer;

        Camera m_Camera;

        YYPostProcessRenderContext m_CurrentContext;

        YYPropertySheetFactory m_PropertySheetFactory;


        YYTargetPool m_TargetPool;

        [SerializeField]
        YYPostProcessResources m_Resources;

        [NonSerialized]
        YYPostProcessResources m_OldResources;

        private void Awake()
        {
            m_Camera = GetComponent<Camera>();
            m_Camera.forceIntoRenderTexture = true;
            

            m_CurrentContext = new YYPostProcessRenderContext();

            m_TargetPool = new YYTargetPool();

           
        }



        private void OnEnable()
        {
            m_LegacyCmdBuffer = new CommandBuffer { name = "yy-post-processing" };
            m_PropertySheetFactory = new YYPropertySheetFactory();

            m_Camera.AddCommandBuffer(CameraEvent.BeforeImageEffects, m_LegacyCmdBuffer);
           
        }


        //private void OnPreRender()
        //{
        //    BuildCommandBuffers();
        //}

        private void OnPreCull()
        {
            BuildCommandBuffers();
        }


        //YYBloom YYBloom;

        void BuildCommandBuffers()
        {
            var context = m_CurrentContext;
            var sourceFormat = RenderTextureFormat.Default;



            context.Reset();

            context.camera = m_Camera;

            if (m_OldResources != m_Resources)
            {
                YYRuntimeUtilities.UpdateResources(m_Resources);
                m_OldResources = m_Resources;
            }

            context.resources = m_Resources;

          
            m_LegacyCmdBuffer.Clear();

            m_TargetPool.Reset();



            var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);
            context.command = m_LegacyCmdBuffer;

            context.propertySheets = m_PropertySheetFactory;

            context.source = cameraTarget;
            context.destination = cameraTarget;

            //var sourceFormat = m_Camera.allowHDR ? RuntimeUtilities.defaultHDRRenderTextureFormat : RenderTextureFormat.Default;

            context.sourceFormat = sourceFormat; 

            ///  context.source   转移   
            int tempRt = -1;
            //if(true)
            {
                tempRt = m_TargetPool.Get();
                context.GetScreenSpaceTemporaryRT(m_LegacyCmdBuffer, tempRt, 0, sourceFormat, RenderTextureReadWrite.Default);
                //context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw_stereo, th);

                m_LegacyCmdBuffer.BuiltinBlit(cameraTarget, tempRt, YYRuntimeUtilities.copyStdMaterial, 0);

                //cmd.Blit(source, destination, mat, pass);
                //m_LegacyCmdBuffer.Blit(cameraTarget, tempRt);

                context.source = tempRt;
            }
            ///

            //GetComponents<YYPostProcessEffectRenderer>

            //GetComponent<YYBloom>().Render(context);

            YYPostProcessEffectRenderer[] yYPostProcessEffectRenderers = GetComponents<YYPostProcessEffectRenderer>();

            for(int i = 0;i< yYPostProcessEffectRenderers.Length;i++)
            {
                yYPostProcessEffectRenderers[i].Render(context);
            }



            //int mipUp = Shader.PropertyToID("_BloomMipDown" + 0);
            //m_LegacyCmdBuffer.GetTemporaryRT(mipUp, Screen.width, Screen.height);

            //
            var cmd = context.command;
            //var uberSheet = context.propertySheets.Get(Shader.Find("YY/PostProcess/YYUber"));
            var uberSheet = context.propertySheets.Get(context.resources.shaders.uber);
            cmd.BlitFullscreenTriangle(context.source, context.destination, uberSheet, 0);



        }


        private void OnDisable()
        {
            m_LegacyCmdBuffer.Clear();
            if (m_Camera)
            {
                m_Camera.RemoveCommandBuffer(CameraEvent.BeforeImageEffects, m_LegacyCmdBuffer);
            }
            m_LegacyCmdBuffer = null;

            m_PropertySheetFactory.Release();
        }

    }
}
